﻿using Basic.WxApiRemoteModel;
using Basic.WxModel.PlatformBind;
using Basic.WxRepository;
using WeDonekRpc.CacheClient.Interface;
using WeDonekRpc.Helper;

namespace Basic.WxCollect.lmpl
{
    internal class WxPlatformBindCollect : IWxPlatformBindCollect
    {
        private readonly IWxPlatformBindRepository _PlatformBind;
        private readonly ICacheController _Cache;
        private static readonly string _CacheKey = "PlatformBind";
        public WxPlatformBindCollect (IWxPlatformBindRepository platform, ICacheController cache)
        {
            this._PlatformBind = platform;
            this._Cache = cache;
        }
        public void SetPrower (string appId, string wxAppId, WxPrower[] prowers)
        {
            WxPlatformBase obj = this._PlatformBind.Find<WxPlatformBase>(appId, wxAppId);
            if (obj != null && !obj.WxPrower.IsEquals(prowers))
            {
                this._PlatformBind.SetPrower(obj.Id, prowers);
                this._Clear(appId, wxAppId);
            }
        }
        public string GetAvailableAppId (string wxAppId, WxPrower prower)
        {
            var dtos = this._PlatformBind.GetBinds(wxAppId, a => new
            {
                a.AppId,
                a.WxPrower
            });
            string appId = dtos.Find(c => c.WxPrower.Contains(prower), c => c.AppId);
            if (appId.IsNull())
            {
                throw new ErrorException("wx.mer.no.accredit", ( (int)prower ).ToString());
            }
            return appId;
        }
        public void Sync (WxPlatformBindAdd obj)
        {
            long id = this._PlatformBind.FindId(obj.AppId, obj.WxAppId);
            if (id == 0)
            {
                this._PlatformBind.Add(obj);
            }
            else
            {
                this._PlatformBind.Set(id, obj.RefreshToken, obj.WxPrower);
            }
            this._Clear(obj.AppId, obj.WxAppId);
        }
        private void _Clear (string appId, string wxAppId)
        {
            string key = string.Join("_", _CacheKey, appId, wxAppId);
            _ = this._Cache.Remove(key);
        }
        public WxPlatformBindDto Get (string appId, string wxAppId)
        {
            string key = string.Join("_", _CacheKey, appId, wxAppId);
            if (!this._Cache.TryGet(key, out WxPlatformBindDto dto))
            {
                dto = this._PlatformBind.Find<WxPlatformBindDto>(appId, wxAppId);
                if (dto == null)
                {
                    _ = this._Cache.Add(key, dto, new TimeSpan(0, 1, 0));
                }
                else
                {
                    _ = this._Cache.Add(key, dto);
                }
            }
            if (dto == null)
            {
                throw new ErrorException("wx.platform.bind.not.find");
            }
            return dto;
        }

        public void Cancel (string appId, string wxAppId)
        {
            WxPlatformBase obj = this._PlatformBind.Find<WxPlatformBase>(appId, wxAppId);
            if (obj != null && obj.IsBind)
            {
                this._PlatformBind.Cancel(obj.Id);
                this._Clear(appId, wxAppId);
            }
        }

        public void SetRefreshToken (WxPlatformBindDto sour, string refresh_token)
        {
            this._PlatformBind.SetRefreshToken(sour.Id, refresh_token);
            this._Clear(sour.AppId, sour.WxAppId);
        }
    }
}
